home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / basic / dir_bas.exe / DIRDEMO.BAS < prev    next >
Encoding:
BASIC Source File  |  1992-08-26  |  39.3 KB  |  994 lines

  1. '       *** DIRDEMO.BAS ***
  2. '
  3. '       Fairchild Computer Services
  4. '       Route 5, Box 523-12
  5. '       Wills Point, TX   75169
  6. '       (903) 873-2114
  7. '
  8. '**************************** GENERAL NOTATIONS ***************************
  9. '
  10. '
  11. '  This program is a half-way decent example of how to use dir.bas.
  12. '
  13. '
  14. '
  15. '                               Enjoy!!                                -jmf
  16. '
  17. '
  18. '**************************************************************************
  19.  
  20. '************************** COMMAND LINE CREATION *************************
  21. ' To make a standalone executable:
  22. '   First, create DIR.QLB & DIR.LIB (see COMMAND LINE CREATION in DIR.BAS);
  23. ' BC   DIRDEMO/O/AH/T/C:512;
  24. ' LINK DIRDEMO/EX/NOE/NOD:BRUN45.LIB
  25. '      DIRDEMO              
  26. '      NUL               
  27. '      BCOM45.LIB+       
  28. '      DIR.LIB           
  29. '**************************************************************************
  30.  
  31. '************************** FUNCTION DECLARATIONS *************************
  32.  
  33.   DECLARE FUNCTION CreateBoxLine$ (RecordNumber%) 'Creates new line in box
  34.   DECLARE FUNCTION LastOccurrence% (text$, LookString$) 'Finds string
  35.   DECLARE FUNCTION VideoSegment! ()     'Retrieves video memory segment
  36.  
  37. '**************************************************************************
  38.  
  39. '************************* SUBROUTINE DECLARATIONS ************************
  40.  
  41.   DECLARE SUB Center (row%, lcol%, rcol%, text$) 'Centers text
  42.   DECLARE SUB ClearBox (x1%, y1%, x2%, y2%)      'Clears window area
  43.   DECLARE SUB CreateBox ()              'Creates directory box
  44.   DECLARE SUB DirTotals (Directory$)    'Returns totals for files in dir
  45.   DECLARE SUB DisplayDir (DirEntry%)    'Display dir entry info in box
  46.   DECLARE SUB DisplayHelp ()            'Display help line(s)
  47.   DECLARE SUB DisplayDirStats ()        'Display directory entry stats
  48.   DECLARE SUB DisplayMemStats ()        'Display memory statistics
  49.   DECLARE SUB DisplayTotals ()          'Display totals info
  50.   DECLARE SUB DoKeystroke ()            'Sub to evaluate & do keystroke(s)
  51.   DECLARE SUB ExitLogo ()               'Let em know who we are...
  52.   DECLARE SUB GetDir ()                 'Gets directory entry information
  53.   DECLARE SUB GrandTotals (Directory$)  'Sub to calc dir and sub-dirs
  54.   DECLARE SUB ReverseLine (row%, lcol%, rcol%) 'Used to reverse video a line
  55.   DECLARE SUB ScrollDown (text$)        'Scrolls box lines down 1
  56.   DECLARE SUB ScrollUp (text$)          'Scrolls box lines up 1
  57.   DECLARE SUB SortDir (count%)          'Used to sort all directory entries
  58.  
  59. '**************************************************************************
  60.  
  61. '******************* CONSTANT/INCLUDE FILE DECLARATIONS *******************
  62.  
  63.   ' $INCLUDE: 'DIR.INC'                 'Use this for DIR.BAS declares, etc.
  64.   ' $INCLUDE: 'QB.BI'                   'Use this for interrupt calls
  65.  
  66.   ' The following are used by DrawBox
  67.   CONST coloronly% = 1                  'Color box only (don't erase chars)
  68.   CONST fillonly% = 2                   'Fill box only (erase all chars)
  69.   CONST colorandfill% = 3               'Color box and erase box contents
  70.   CONST reverseonly% = 4                'Reverse color of box only
  71.   CONST reverseandfill% = 5             'Reverse color and fill it
  72.  
  73.   ' The following are used by DoKeystroke (Action%)
  74.   CONST NextDir% = 1                    'Do next dir call
  75.   CONST EndIt% = 2                      'Goto end of program
  76.  
  77. '**************************************************************************
  78.  
  79. '************************ DATABASE (TYPE) LAYOUTS *************************
  80. '**************************************************************************
  81.  
  82. '**************** DECLARE GLOBAL (COMMON) SHARED VARIABLES ****************
  83. '**************************************************************************
  84.  
  85. '******************** DECLARE LOCAL (SHARED) VARIABLES ********************
  86.  
  87.   DIM SHARED Action%                    'Action to be done after DoKeyStroke
  88.   DIM SHARED BottomDisplay%             'Last MyDir entry in window
  89.   DIM SHARED BoxLine$(24)               'Holds lines for box printing
  90.   DIM SHARED BoxLength%, BoxHeight%     'Length and height of box
  91.   DIM SHARED BoxRow%, BoxCol%           'Start position of box row & column
  92.   DIM SHARED BoxCol1%, BoxCol2%         'Start and end position of box cols
  93.   DIM SHARED DirChoice%                 'MyDir() choice
  94.   DIM SHARED HoldCount%                 'Dir Entry counter
  95.   DIM SHARED FirstPrintRow%             'Start screen line of box line prints
  96.   DIM SHARED LastBoxRow%                'Ending screen line of box
  97.   DIM SHARED LastPrintLine%             'Ending position of box line prints
  98.   DIM SHARED LastPrintRow%              'Ending screen line of box line prints
  99.   DIM SHARED MainBg%, MainFg%           'Screen colors
  100.   DIM SHARED MyDirCount%                'Count of (sub-)dirs in current dir
  101.   DIM SHARED NewLine%, OldLine%         'Box print line number holder var's
  102.   DIM SHARED SubDir%                    'Sub directory flag
  103.   DIM SHARED TopDisplay%                'Top MyDir entry in window
  104.   DIM SHARED FC, SC, TS                 'Share count variables
  105.  
  106. '**************************************************************************
  107.  
  108. '**************************** CREATE VARIABLES ****************************
  109. '**************************************************************************
  110.  
  111. '*************************** DATA DECLARATIONS ****************************
  112. '**************************************************************************
  113.  
  114. '************************* MAIN SUBROUTINE CALLS **************************
  115. Main:
  116.   ' The following are the changeable attributes
  117.   MainBg% = 7                           'Main (screen) background color
  118.   MainFg% = 0                           'Main (screen) foreground color
  119.   BoxRow% = 1                           'Row of upper left corner of box
  120.   BoxCol% = 1                           'Column of upper left corner of box
  121.   BoxHeight% = 13                       'Height of box (from BoxRow%)
  122.  
  123.   ' Let's get started...
  124.   COLOR MainBg%, MainFg%                'Color screen
  125.   CLS                                   'Clear screen
  126.  
  127. MainGetDir:
  128.   HoldCount% = DirCount%("*.*")         'Do a directory entry count
  129.   REDIM SHARED MyDir(HoldCount%) AS DirType 'Dimension array
  130.   CreateBox                             'Paint box to screen
  131.   Center FirstPrintRow%, BoxCol1%, BoxCol2%, "Directory Entries Found : " + STR$(HoldCount%)
  132.   GetDir                                'Get the entries
  133.   OldLine% = 1: NewLine% = 1            'Init reverse bar counters
  134.   DirChoice% = 1                        'Number of Mydir() record
  135.   DisplayDir (DirChoice%)               'Display current entries in box
  136.   ReverseLine FirstPrintRow%, BoxCol1%, BoxCol2% 'Highlight first entry
  137.   DisplayDirStats                       'Display directory stat info
  138.   DisplayMemStats                       'Display memory stat info
  139.   DisplayTotals                         'Display other totals stats
  140.   DisplayHelp                           'Display help info
  141.   DoKeystroke                           'Get/do user's keystroke(s)
  142.   SELECT CASE Action%                   'When done...any action to take?
  143.     CASE False%                         'No.
  144.       GOTO EndProgram                   ' we be done...
  145.     CASE NextDir%                       'Yes.
  146.       GOTO MainGetDir                   ' we got another dir to display
  147.     CASE EndIt%                         'Yes.
  148.       GOTO EndProgram                   ' bye, bye...
  149.   END SELECT
  150.  
  151. '**************************************************************************
  152.  
  153. '*************************** DATA DECLARATIONS ****************************
  154. '**************************************************************************
  155.  
  156. '***************************** EXIT ROUTINES ******************************
  157. EndProgram:
  158.   ExitLogo
  159. END
  160. '**************************************************************************
  161.  
  162. SUB Center (row%, lcol%, rcol%, text$)
  163.  
  164.   ' This subroutine will center text$ on row%, between lcol% and rcol%
  165.  
  166.   col% = lcol% + INT((rcol% - lcol% - LEN(text$)) / 2) + 2 'Calc cursor pos
  167.   LOCATE row%, col%                       'Position cursor
  168.   PRINT text$;                            'Print actual text
  169.  
  170. END SUB
  171.  
  172. SUB ClearBox (x1%, y1%, x2%, y2%)
  173.  
  174.   ' This subroutine will clear the contents of a window.
  175.  
  176.   InRegsX.AX = &H600                    'function 6 + number of scroll lines
  177.   fg% = MainBg% * 256                   'Calc BH foreground
  178.   bg% = MainFg% * 4096                  'Calc BH background
  179.   InRegsX.BX = fg% + bg%                'Blanked line color
  180.   CH% = x1% * 256                       'CH=top row
  181.   InRegsX.CX = CH% + y1%                'CL=left column
  182.   DH% = (x2% - 1) * 256                 'DH=bottom row
  183.   InRegsX.DX = DH% + y2%                'DL=right column
  184.   CALL INTERRUPTX(&H10, InRegsX, OutRegsX) 'Call interrupt 16
  185.  
  186. END SUB
  187.  
  188. SUB CreateBox
  189.  
  190.   ' This subroutine will create the box used for the directory display
  191.   ' and manipulation.
  192.  
  193.   a2$ = CHR$(205)                       'Double across line
  194.   br$ = CHR$(179)                       'Save bar variable
  195.   s1$ = " "                             'Save space variable
  196.   t1$ = null$                           'Temporary variable
  197.   xt$ = CHR$(209)                       'Single across, middle down line
  198.   xl$ = CHR$(207)                       'Single across, middle up
  199.   BoxLength% = 47                       'Fixed (non-changeable) box length
  200.   GOSUB CheckBoxDimensions              'Ensure good dimensions
  201.   FirstPrintRow% = BoxRow% + 4          'First physical row for box prints
  202.   LastBoxRow% = BoxRow% + BoxHeight%    'Last physical row of box
  203.   BoxCol1% = BoxCol%                    'Save left column for ReverseLine
  204.   BoxCol2% = BoxCol1% + BoxLength%      'Save right column for ReverseLine
  205.  
  206.   BoxLine$(1) = CHR$(213) + STRING$(48, 205) + CHR$(184)
  207.   BoxLine$(2) = br$ + SPACE$(48) + br$
  208.   FOR c% = 1 TO 5: t1$ = t1$ + xt$ + a2$: NEXT
  209.   BoxLine$(3) = CHR$(198) + STRING$(12, 205) + xt$ + STRING$(9, 205) + xt$ + STRING$(8, 205) + xt$ + STRING$(6, 205) + t1$ + CHR$(181)
  210.   t$ = br$ + "    Name    " + br$ + "   Size  " + br$ + "  Date  " + br$ + " Time "
  211.   BoxLine$(4) = t$ + br$ + "R" + br$ + "H" + br$ + "S" + br$ + "A" + br$ + "D" + br$
  212.   t1$ = null$
  213.   FOR c% = 1 TO 5: t1$ = t1$ + s1$ + br$: NEXT
  214.   FOR c% = 5 TO BoxHeight%
  215.     BoxLine$(c%) = br$ + SPACE$(12) + br$ + SPACE$(9) + br$ + SPACE$(8) + br$ + SPACE$(6) + br$ + t1$
  216.   NEXT
  217.   t1$ = null$
  218.   FOR c% = 1 TO 5: t1$ = t1$ + xl$ + a2$: NEXT
  219.   BoxLine$(BoxHeight% + 1) = CHR$(212) + STRING$(12, 205) + xl$ + STRING$(9, 205) + xl$ + STRING$(8, 205) + xl$ + STRING$(6, 205) + t1$ + CHR$(190)
  220.   FOR c% = BoxRow% TO BoxRow% + BoxHeight% + 1
  221.     LOCATE c%, BoxCol%
  222.     PRINT BoxLine$(c% - BoxRow% + 1);
  223.   NEXT
  224. GOTO ExitCreateBox
  225.  
  226. CheckBoxDimensions:
  227.   SELECT CASE BoxCol%
  228.     CASE IS < 1
  229.       BoxCol% = 1
  230.     CASE IS > 80 - BoxLength% - 2
  231.       BoxCol% = 80 - BoxLength% - 2
  232.   END SELECT
  233.   SELECT CASE BoxRow% + BoxHeight%
  234.     CASE IS > 14
  235.       BoxHeight% = 14 - BoxRow%
  236.   END SELECT
  237.   SELECT CASE BoxRow%
  238.     CASE IS < 1
  239.       BoxRow% = 1
  240.     CASE IS > 8
  241.       BoxRow% = 8
  242.   END SELECT
  243.   SELECT CASE BoxHeight%
  244.     CASE IS < 6
  245.       BoxHeight% = 6
  246.     CASE IS > 14
  247.       BoxHeight% = 14
  248.   END SELECT
  249. RETURN
  250.  
  251. ExitCreateBox:
  252. END SUB
  253.  
  254. FUNCTION CreateBoxLine$ (RecordNumber%)
  255.              
  256.   ' This function will build a line to be displayed within the box
  257.   ' created by CreateBox
  258.  
  259.   as$ = "*"                             'Save asterisk variable
  260.   br$ = CHR$(179)                       'Save up-down bar variable
  261.   s1$ = " "                             'Save space variable
  262.   t1$ = null$                           'Temporary save variable
  263.   REDIM f$(5)                           'DIMension flag array
  264.   FOR c% = 1 TO 5: f$(c%) = s1$: NEXT   'Initialize flags
  265.   t$ = MyDir(RecordNumber%).EntryName + br$ 'Start row w/entry and bar
  266.   IF MyDir(RecordNumber%).DirectoryFlag THEN   'Directory?
  267.     t$ = t$ + " < DIR > "               'If directory, so display
  268.     f$(5) = as$                         'Set flag for display on
  269.   ELSE                                  'If not...
  270.     t$ = t$ + ConvertSize$(MyDir(RecordNumber%).EntrySize) 'Display size
  271.   END IF
  272.   t$ = t$ + br$ + ConvertDate$(MyDir(RecordNumber%).EntryDate)
  273.   t$ = t$ + br$ + ConvertTime$(MyDir(RecordNumber%).EntryTime) + br$
  274.   IF MyDir(RecordNumber%).ReadOnlyFlag THEN f$(1) = as$
  275.   IF MyDir(RecordNumber%).HiddenFlag THEN f$(2) = as$
  276.   IF MyDir(RecordNumber%).SystemFlag THEN f$(3) = as$
  277.   IF MyDir(RecordNumber%).ArchiveFlag THEN f$(4) = as$
  278.   FOR c% = 1 TO 5: t1$ = t1$ + f$(c%) + br$: NEXT                                 'Try again
  279.   t$ = t$ + t1$                         'Make final variable
  280.  
  281.   CreateBoxLine$ = t$                   ' and return it
  282.  
  283. END FUNCTION
  284.  
  285. SUB DisplayDir (DirEntry%)
  286.  
  287.   ' This subroutine will build the directory entry display
  288.  
  289.   TopDisplay% = DirEntry%
  290.   IF HoldCount% + SubDir% <= BoxHeight% - FirstPrintRow% + BoxRow% THEN
  291.     LastPrintRow% = FirstPrintRow% + HoldCount% + SubDir%
  292.     LastPrintLine% = HoldCount% + SubDir%
  293.   ELSE
  294.     LastPrintRow% = BoxRow% + BoxHeight% - 1
  295.     LastPrintLine% = BoxHeight% - FirstPrintRow% + BoxRow%
  296.   END IF
  297.   t$ = CurrentDir$
  298.   IF LEN(t$) >= BoxLength% THEN
  299.     t$ = LEFT$(t$, INSTR(t$, ":")) + "\..." + RIGHT$(t$, BoxLength% - 5)
  300.   END IF
  301.   Center BoxRow% + 1, BoxCol1%, BoxCol2%, t$
  302.   FOR c% = 0 TO LastPrintLine% - 1
  303.     LOCATE c% + FirstPrintRow%, BoxCol% + 1
  304.     PRINT CreateBoxLine$(DirEntry% + c%);
  305.   NEXT
  306.   BottomDisplay% = DirEntry% + LastPrintLine% - 1
  307.  
  308. END SUB
  309.  
  310. SUB DisplayDirStats
  311.  
  312.   BoxCol3% = BoxCol2% + 3               'Save column variable for printing
  313.   br$ = CHR$(179) + " "                 'Bar plus space
  314.   fl% = 3                               'Set MaskIt$ field length variable
  315.   HS = 0                                'Initialize hidden size variable
  316.   NS = 0                                'Initialize non-dir size variable
  317.   RS = 0                                'Initialize read-only size variable
  318.   XS = 0                                'Initialize archived size variable
  319.   TR% = 0                               'Initialize total reserved counter
  320.   TH% = 0                               'Initialize total hidden counter
  321.   TS% = 0                               'Initialize total system counter
  322.   TA% = 0                               'Initialize total archived counter
  323.   pc% = 1
  324.  
  325.   x1% = BoxRow%                         'Upper row of display area
  326.   y1% = BoxCol3% - 1                    'Left col of display area
  327.   x2% = x1% + pc% + 7                   'Lower row of display area
  328.   y2% = 79                              'Right col of display area
  329.  
  330.   ClearBox x1%, y1%, x2%, y2%           'Clear area for display
  331.  
  332.   c% = 0                                'Initialize line counter
  333.   DO
  334.     c% = c% + 1
  335.     IF NOT MyDir(c%).DirectoryFlag THEN NS = NS + MyDir(c%).EntrySize
  336.     IF MyDir(c%).ReadOnlyFlag THEN RS = RS + MyDir(c%).EntrySize
  337.     IF MyDir(c%).HiddenFlag THEN HS = HS + MyDir(c%).EntrySize
  338.     IF MyDir(c%).SystemFlag THEN SS = SS + MyDir(c%).EntrySize
  339.     IF MyDir(c%).ArchiveFlag THEN XS = XS + MyDir(c%).EntrySize
  340.   LOOP UNTIL c% = HoldCount% + SubDir%
  341.   t% = 1
  342.   WHILE t% <= HoldCount% + SubDir%
  343.     IF MyDir(t%).ReadOnlyFlag THEN TR% = TR% + 1
  344.     IF MyDir(t%).HiddenFlag THEN TH% = TH% + 1
  345.     IF MyDir(t%).SystemFlag THEN TS% = TS% + 1
  346.     IF MyDir(t%).ArchiveFlag THEN TA% = TA% + 1
  347.     t% = t% + 1
  348.   WEND
  349.   c$ = "Attrib         Total bytes"
  350.   GOSUB PrintLine
  351.   ReverseLine BoxRow% + pc% - 1, BoxCol2% + 2, 79
  352.   c$ = "Reserved: " + MaskIt$(STR$(TR%), fl%, "R") + br$ + MaskIt$(STR$(RS), fl%, ",")
  353.   GOSUB PrintLine
  354.   c$ = "Hidden  : " + MaskIt$(STR$(TH%), fl%, "R") + br$ + MaskIt$(STR$(HS), fl%, ",")
  355.   GOSUB PrintLine
  356.   c$ = "System  : " + MaskIt$(STR$(TS%), fl%, "R") + br$ + MaskIt$(STR$(SS), fl%, ",")
  357.   GOSUB PrintLine
  358.   c$ = "Archived: " + MaskIt$(STR$(TA%), fl%, "R") + br$ + MaskIt$(STR$(XS), fl%, ",")
  359.   GOSUB PrintLine
  360.   c$ = "Files          Total bytes"
  361.   GOSUB PrintLine
  362.   ReverseLine BoxRow% + pc% - 1, BoxCol2% + 2, 79
  363.   SELECT CASE SubDir%
  364.     CASE True%
  365.       c$ = "Sub-dirs: " + MaskIt$(STR$(MyDirCount% - SubDir%), fl%, "R") + br$
  366.     CASE False%
  367.       c$ = "Dirs    : " + MaskIt$(STR$(MyDirCount%), fl%, "R") + br$
  368.   END SELECT
  369.   GOSUB PrintLine
  370.   c$ = "Non-Dir : " + MaskIt$(LTRIM$(STR$(HoldCount% - MyDirCount% + SubDir%)), fl%, "R") + br$ + MaskIt$(STR$(NS), fl%, ",")
  371.   GOSUB PrintLine
  372.  
  373. GOTO ExitDisplayDirStats
  374.  
  375. PrintLine:
  376.   LOCATE BoxRow% + pc%, BoxCol3%
  377.   PRINT c$;
  378.   pc% = pc% + 1
  379. RETURN
  380.  
  381. ExitDisplayDirStats:
  382. END SUB
  383.  
  384. SUB DisplayHelp
  385.  
  386.   LOCATE 23, 1
  387.   PRINT "  ESC  = Exit         "; CHR$(17); CHR$(196); CHR$(217);
  388.   PRINT "  = Up/Down (on < DIR >)        A-Z  = Select file/dir";
  389.   ReverseLine 23, 1, 5
  390.   ReverseLine 23, 21, 25
  391.   ReverseLine 23, 56, 60
  392.   LOCATE 24, 1
  393.   PRINT "        F2  = Display total bytes used by highlighted dir and all sub-dirs";
  394.   ReverseLine 24, 7, 10
  395.  
  396. ExitDisplayHelp:
  397. END SUB
  398.  
  399. SUB DisplayMemStats
  400.  
  401.   x1% = LastBoxRow% + 4                 'Upper row of display area
  402.   y1% = BoxCol1%                        'Left col of display area
  403.   x2% = x1% + 3                         'Lower row of display area
  404.   y2% = BoxCol2%                        'Right col of display area
  405.  
  406.   ClearBox x1% - 1, y1%, x2%, y2%       'Clear display area
  407.  
  408.   Center x1%, y1%, y2%, "Memory"           'Create header
  409.   ReverseLine x1%, y1%, y2%                'Create header line
  410.  
  411.   MA$ = MaskIt$(STR$(FRE(-1)), 7, ",")     'Calc avail memory
  412.   CALL INTERRUPTX(&H12, InRegsX, OutRegsX) 'Make interrupt call
  413.   MemKB = OutRegsX.AX                      'Get total memory (in KiloBytes)
  414.   Mem = MemKB * 1024                       'Available memory (total bytes)
  415.   TM$ = MaskIt$(STR$(Mem), 7, ",")         'Get total memory
  416.  
  417.   ' Display statistics
  418.   Center x1% + 1, y1%, y2%, TM$ + " Bytes Total Memory"
  419.   Center x1% + 2, y1%, y2%, MA$ + " Bytes Memory Free "
  420.   ReverseLine x1% + 3, y1%, y2%
  421.  
  422. ExitDisplayMemStats:
  423. END SUB
  424.  
  425. SUB DisplayTotals STATIC
  426.  
  427.   IF TotalsDisplayed% = False% THEN
  428.     d$ = LEFT$(CurrentDir$, 1)          'Get current drive letter
  429.     t% = ASC(d$) - 64                   'Set correct drive value(A=1,etc)
  430.     InRegsX.AX = &H3600                 'AH=Hex 36 (function)
  431.     InRegsX.DX = t%                     'DL=Drive number
  432.     CALL INTERRUPTX(&H21, InRegsX, OutRegsX) 'Interrupt 21
  433.     AXReg& = OutRegsX.AX                'AX Register value
  434.     SectorsPerCluster& = AXReg& AND 255 'AL=Sectors per cluster
  435.     AvailClusters& = OutRegsX.BX        'Get space available on disk
  436.     SectorSize& = OutRegsX.CX           'CX=Sector size (in bytes)
  437.     TotalClusters& = OutRegsX.DX        'DX=Total number clusters on disk
  438.     TotalAvail& = SectorsPerCluster& * SectorSize& * AvailClusters&
  439.     InRegsX.AX = &H1C00                 'AH=Hex 1C (function)
  440.     InRegsX.DX = t%                     'DL=Drive number
  441.     CALL INTERRUPTX(&H21, InRegsX, OutRegsX) 'Interrupt 21
  442.     SectorsPerCluster& = OutRegsX.AX AND 255 'AL=Sectors per cluster
  443.     Descriptor% = OutRegsX.BX           'BX=Offset of descriptor info
  444.     SectorSize& = OutRegsX.CX           'CX=Sector size (in bytes)
  445.     BufferSegment% = OutRegsX.DS        'DS=Segment of descriptor info
  446.     TotalClusters& = OutRegsX.DX        'DX=Total number clusters on disk
  447.     DEF SEG = BufferSegment%            'Set memory segment to descriptor's
  448.     Descriptor$ = HEX$(PEEK(Descriptor%)) 'Get the thing
  449.     DEF SEG                             'Set back to Basic
  450.     TotalBytes& = SectorsPerCluster& * SectorSize& * TotalClusters&
  451.  
  452.     Center LastBoxRow% + 1, BoxCol1%, BoxCol2%, "Drive " + d$ + ":"
  453.     ReverseLine LastBoxRow% + 1, BoxCol1%, BoxCol2%
  454.     t$ = MaskIt$(STR$(TotalBytes&), 20, ",") + " total bytes  on drive " + d$ + ":"
  455.     Center LastBoxRow% + 2, BoxCol1%, BoxCol2%, t$
  456.     t$ = MaskIt$(STR$(TotalAvail&), 20, ",") + " bytes available drive " + d$ + ":"
  457.     Center LastBoxRow% + 3, BoxCol1%, BoxCol2%, t$
  458.   END IF
  459.   TotalsDisplayed% = True%
  460.  
  461. END SUB
  462.  
  463. SUB DoKeystroke
  464.  
  465.   ' This subroutine accepts input from the keyboard, determines it's
  466.   ' validity, and takes the correct action (if any is needed)
  467.  
  468. GetKeystroke:
  469.   Action% = False%
  470.   DO
  471.       K$ = INKEY$
  472.   LOOP WHILE K$ = null$
  473.   Keys% = (ASC(RIGHT$(K$, 1)))
  474.   ScanKey% = (ASC(LEFT$(K$, 1)))
  475.   ValidKey% = True%: DoReverseLine% = True%
  476.   IF ScanKey% = 0 THEN
  477.     SELECT CASE Keys%
  478.       CASE 60                           '<F2> key
  479.         t$ = RTRIM$(MyDir(DirChoice%).EntryName)
  480.         IF t$ = ".." OR MyDir(DirChoice%).DirectoryFlag <> 16 THEN
  481.           BEEP
  482.         ELSE
  483.           IF SubDir% THEN s$ = "\" ELSE s$ = null$
  484.           GrandTotals CurrentDir$ + s$ + t$
  485.         END IF
  486.         DoReverseLine% = False%
  487.       CASE 71                           '<HOME> key
  488.         IF DirChoice% <> 1 THEN
  489.           IF TopDisplay% <> 1 THEN
  490.             OldLine% = 1
  491.             NewLine% = 1
  492.             DirChoice% = 1
  493.             ClearBox FirstPrintRow%, BoxCol%, LastPrintRow%, BoxCol1% + BoxLength%
  494.             DisplayDir (DirChoice%)
  495.             ReverseLine FirstPrintRow%, BoxCol1%, BoxCol2%
  496.             DoReverseLine% = False%
  497.           ELSE
  498.             OldLine% = NewLine%
  499.             DirChoice% = 1
  500.             NewLine% = 1
  501.           END IF
  502.         ELSE
  503.           DoReverseLine% = False%
  504.         END IF
  505.       CASE 72                           '<UP ARROW> key
  506.         IF DirChoice% = 1 THEN
  507.           NewLine% = 1
  508.           OldLine% = NewLine%
  509.           DoReverseLine% = False%
  510.         ELSE
  511.           IF NewLine% = 1 THEN
  512.             DirChoice% = DirChoice% - 1
  513.             ScrollDown CreateBoxLine$(DirChoice%)
  514.             OldLine% = NewLine% + 1
  515.             NewLine% = 1
  516.             TopDisplay% = TopDisplay% - 1
  517.             BottomDisplay% = BottomDisplay% - 1
  518.           ELSE
  519.             OldLine% = NewLine%
  520.             NewLine% = NewLine% - 1
  521.             DirChoice% = DirChoice% - 1
  522.           END IF
  523.         END IF
  524.       CASE 73                           '<PGUP> key
  525.         IF DirChoice% > LastPrintLine% THEN
  526.           DirChoice% = DirChoice% - LastPrintLine%
  527.           IF DirChoice% > LastPrintLine% THEN
  528.             ClearBox FirstPrintRow%, BoxCol%, LastPrintRow%, BoxCol1% + BoxLength%
  529.             DisplayDir (DirChoice%)
  530.             ReverseLine FirstPrintRow%, BoxCol1%, BoxCol2%
  531.             OldLine% = 1
  532.             NewLine% = OldLine%
  533.             DoReverseLine% = False%
  534.           ELSE
  535.             temp% = 1
  536.             ClearBox FirstPrintRow%, BoxCol%, LastPrintRow%, BoxCol1% + BoxLength%
  537.             DisplayDir (temp%)
  538.             temp% = FirstPrintRow% + DirChoice% - temp%
  539.             ReverseLine temp%, BoxCol1%, BoxCol2%
  540.             OldLine% = DirChoice%
  541.             NewLine% = OldLine%
  542.             DoReverseLine% = False%
  543.           END IF
  544.         ELSE
  545.           IF DirChoice% <> NewLine% THEN
  546.             DirChoice% = 1
  547.             ClearBox FirstPrintRow%, BoxCol%, LastPrintRow%, BoxCol1% + BoxLength%
  548.             DisplayDir (DirChoice%)
  549.             ReverseLine FirstPrintRow%, BoxCol1%, BoxCol2%
  550.             OldLine% = 1
  551.             NewLine% = OldLine%
  552.             DoReverseLine% = False%
  553.           ELSE
  554.             IF DirChoice% = 1 THEN
  555.               DoReverseLine% = False%
  556.             ELSE
  557.               DirChoice% = 1
  558.               OldLine% = NewLine%
  559.               NewLine% = 1
  560.             END IF
  561.           END IF
  562.         END IF
  563.       CASE 79                           '<END> key
  564.         IF DirChoice% <> HoldCount% + SubDir% THEN
  565.           IF BottomDisplay% <> HoldCount% + SubDir% THEN
  566.             DirChoice% = HoldCount% + SubDir% - LastPrintLine% + 1
  567.             ClearBox FirstPrintRow%, BoxCol%, LastPrintRow%, BoxCol1% + BoxLength%
  568.             DisplayDir (DirChoice%)
  569.             ReverseLine LastPrintRow%, BoxCol1%, BoxCol2%
  570.             OldLine% = NewLine%
  571.             NewLine% = LastPrintLine%
  572.             DirChoice% = HoldCount% + SubDir%
  573.             DoReverseLine% = False%
  574.           ELSE
  575.             OldLine% = NewLine%
  576.             DirChoice% = HoldCount% + SubDir%
  577.             NewLine% = LastPrintLine%
  578.           END IF
  579.         ELSE
  580.           DoReverseLine% = False%
  581.         END IF
  582.       CASE 80                           '<DOWN ARROW> key
  583.         IF DirChoice% = HoldCount% + SubDir% THEN
  584.           NewLine% = LastPrintLine%
  585.           OldLine% = NewLine%
  586.           DoReverseLine% = False%
  587.         ELSE
  588.           IF NewLine% = LastPrintLine% THEN
  589.             DirChoice% = DirChoice% + 1
  590.             ScrollUp CreateBoxLine$(DirChoice%)
  591.             OldLine% = NewLine% - 1
  592.             NewLine% = LastPrintLine%
  593.             TopDisplay% = TopDisplay% + 1
  594.             BottomDisplay% = BottomDisplay% + 1
  595.           ELSE
  596.             OldLine% = NewLine%
  597.             NewLine% = NewLine% + 1
  598.             DirChoice% = DirChoice% + 1
  599.           END IF
  600.         END IF
  601.       CASE 81                           '<PGDN> key
  602.         IF DirChoice% + LastPrintLine% <= HoldCount% + SubDir% THEN
  603.           DirChoice% = DirChoice% + LastPrintLine%
  604.           IF DirChoice% + LastPrintLine% <= HoldCount% + SubDir% THEN
  605.             ClearBox FirstPrintRow%, BoxCol%, LastPrintRow%, BoxCol1% + BoxLength%
  606.             DisplayDir (DirChoice%)
  607.             ReverseLine FirstPrintRow%, BoxCol1%, BoxCol2%
  608.             OldLine% = NewLine%
  609.             NewLine% = 1
  610.             DoReverseLine% = False%
  611.           ELSE
  612.             temp% = HoldCount% + SubDir% - LastPrintLine% + 1
  613.             ClearBox FirstPrintRow%, BoxCol%, LastPrintRow%, BoxCol1% + BoxLength%
  614.             DisplayDir (temp%)
  615.             temp% = LastPrintRow% - (HoldCount% + SubDir% - DirChoice%)
  616.             ReverseLine temp%, BoxCol1%, BoxCol2%
  617.             temp% = temp% - FirstPrintRow% + 1
  618.             OldLine% = temp%
  619.             NewLine% = temp%
  620.             DoReverseLine% = False%
  621.           END IF
  622.         ELSE
  623.           IF DirChoice% = HoldCount% + SubDir% THEN
  624.             DoReverseLine% = False%
  625.           ELSE
  626.             OldLine% = NewLine%
  627.             NewLine% = LastPrintLine%
  628.             DirChoice% = HoldCount% + SubDir%
  629.           END IF
  630.         END IF
  631.       CASE ELSE
  632.         ValidKey% = False%              'If not done above, invalid keypress
  633.     END SELECT
  634.   ELSE
  635.     SELECT CASE Keys%
  636.       CASE 13                           '<ENTER> key
  637.         SELECT CASE RTRIM$(MyDir(DirChoice%).EntryName)
  638.           CASE ".."
  639.             SaveDir$ = CurrentDir$
  640.             NewDir$ = LEFT$(SaveDir$, LastOccurrence%(SaveDir$, "\") - 1)
  641.             IF RIGHT$(NewDir$, 1) = ":" THEN NewDir$ = NewDir$ + "\"
  642.             GOTO ChangeDir
  643.           CASE ELSE
  644.             IF MyDir(DirChoice%).DirectoryFlag THEN
  645.               NewDir$ = CurrentDir$
  646.               IF RIGHT$(NewDir$, 1) <> "\" THEN NewDir$ = NewDir$ + "\"
  647.               NewDir$ = NewDir$ + MyDir(DirChoice%).EntryName
  648.               GOTO ChangeDir
  649.             ELSE
  650.               OldLine% = NewLine%
  651.               DoReverseLine% = False%
  652.             END IF
  653.         END SELECT
  654.       CASE 27                           '<ESC> key
  655.         Action% = EndIt%
  656.         EXIT SUB
  657.       CASE 65 TO 90, 97 TO 122          '<A> - <Z> (ALPHA) keys
  658.         SELECT CASE Keys%
  659.           CASE 97 TO 122
  660.             Keys% = Keys% - 32
  661.         END SELECT
  662.         t$ = CHR$(Keys%)
  663.         c% = DirChoice%
  664.         StartPoint% = c%
  665.         EndPoint% = UBOUND(MyDir)
  666.         DO
  667.           c% = c% + 1
  668.           IF c% >= EndPoint% THEN c% = 0
  669.           IF c% = StartPoint% THEN EXIT DO
  670.         LOOP UNTIL t$ = LEFT$(MyDir(c%).EntryName, 1)
  671.         IF c% <> StartPoint% THEN
  672.           IF c% >= TopDisplay% AND c% <= BottomDisplay% THEN
  673.             OldLine% = NewLine%
  674.             NewLine% = c% - TopDisplay% + 1
  675.             DirChoice% = c%
  676.           ELSE
  677.             IF c% < LastPrintLine% THEN
  678.               ClearBox FirstPrintRow%, BoxCol%, LastPrintRow%, BoxCol1% + BoxLength%
  679.               DisplayDir (1)
  680.               ReverseLine FirstPrintRow% + c% - 1, BoxCol1%, BoxCol2%
  681.               DirChoice% = c%
  682.               OldLine% = c%
  683.               NewLine% = c%
  684.               DoReverseLine% = False%
  685.             ELSE
  686.               IF c% + LastPrintLine% > HoldCount% + SubDir% THEN
  687.                 temp% = HoldCount% + SubDir% - LastPrintLine% + 1
  688.                 ClearBox FirstPrintRow%, BoxCol%, LastPrintRow%, BoxCol1% + BoxLength%
  689.                 DisplayDir (temp%)
  690.                 temp% = c% - TopDisplay% + FirstPrintRow%
  691.                 ReverseLine temp%, BoxCol1%, BoxCol2%
  692.                 temp% = temp% - FirstPrintRow% + 1
  693.                 OldLine% = temp%
  694.                 NewLine% = OldLine%
  695.                 DirChoice% = c%
  696.                 DoReverseLine% = False%
  697.               ELSE
  698.                 ClearBox FirstPrintRow%, BoxCol%, LastPrintRow%, BoxCol1% + BoxLength%
  699.                 DisplayDir (c%)
  700.                 ReverseLine FirstPrintRow%, BoxCol1%, BoxCol2%
  701.                 OldLine% = 1
  702.                 NewLine% = OldLine%
  703.                 DirChoice% = c%
  704.                 DoReverseLine% = False%
  705.               END IF
  706.             END IF
  707.           END IF
  708.         ELSE
  709.           DoReverseLine% = False%
  710.         END IF
  711.       CASE ELSE
  712.         ValidKey% = False%              'If not done above, invalid keypress
  713.     END SELECT
  714.   END IF
  715.   IF ValidKey% = True% THEN             'Good keystroke?
  716.     IF DoReverseLine% THEN              'To eliminate snow at top or bottom
  717.       ReverseLine FirstPrintRow% + OldLine% - 1, BoxCol1%, BoxCol2% 'Replace old
  718.       ReverseLine FirstPrintRow% + NewLine% - 1, BoxCol1%, BoxCol2% 'Move bar
  719.     END IF
  720.   END IF
  721.  
  722. GOTO GetKeystroke
  723.  
  724. ChangeDir:
  725.   CHDIR NewDir$
  726.   Action% = NextDir%
  727.  
  728. END SUB
  729.  
  730. SUB ExitLogo
  731.  
  732.   x1% = LastBoxRow% + 1
  733.   y1% = BoxCol2% + 2
  734.   x2% = 22
  735.   y2% = 79
  736.  
  737.   ClearBox x1% - 1, y1% - 1, x2%, y2%
  738.  
  739.   ReverseLine x1%, y1%, y2%
  740.   Center x1% + 1, y1%, y2%, "Fairchild Computer Services"
  741.   Center x1% + 2, y1%, y2%, "Route 5, Box 523-12"
  742.   Center x1% + 3, y1%, y2%, "Wills Point, TX  75169"
  743.   Center x1% + 4, y1%, y2%, "(903) 873-2114"
  744.   Center x1% + 5, y1%, y2%, "Have a great day!!"
  745.   ReverseLine x1% + 6, y1%, y2%
  746.  
  747.   ClearBox 22, 1, 24, 80
  748.   LOCATE 22, 1
  749.  
  750. END SUB
  751.  
  752. SUB GetDir
  753.  
  754.   'Get/Sort directory entries
  755.  
  756.   SubDir% = False%                      'Init Sub directory flag
  757.   SELECT CASE HoldCount%                'How many we gettin?
  758.     CASE 0                              'None?
  759.     CASE ELSE                           ' or some?
  760.       c% = 1                            'Initialize counter
  761.       t$ = Dir$("*.*")                  'Initialize temporary variable
  762.       DO                                'Begin entry-getting loop
  763.         MyDir(c%) = DirRecord           'Load DirRecord into array
  764.         c% = c% + 1                     'Increment counter
  765.         IF RTRIM$(t$) = "." THEN        'Upper directory name?
  766.           c% = c% - 1                   ' if so, decrement counter
  767.           HoldCount% = HoldCount% - 1   ' and totals counter
  768.         END IF
  769.         IF RTRIM$(t$) = ".." THEN       'Is this a subdirectory?
  770.           SubDir% = True%               'yep...
  771.           HoldCount% = HoldCount% - 1   'decrement totals counter
  772.         END IF
  773.         t$ = Dir$(null$)                'Call for next entry
  774.       LOOP UNTIL t$ = null$             'Keep goin until none found
  775.       SortDir HoldCount% + SubDir%      'Sort em
  776.   END SELECT
  777.  
  778. END SUB
  779.  
  780. SUB GrandTotals (Directory$)
  781.  
  782.   x1% = BoxRow% + 9                     'Upper row of display area
  783.   y1% = BoxCol2% + 2                    'Left col of display area
  784.   x2% = x1% + 4                         'Lower row of display area
  785.   y2% = 79                              'Right col of display area
  786.  
  787.   all$ = "\*.*"                         'Save wildcard search to variable
  788.   Directory$ = Directory$ + all$        'Name directory we're totaling
  789.   RootDir$ = LEFT$(Directory$, INSTR(Directory$, all$) - 1)
  790.   t% = LastOccurrence%(RootDir$, "\") + 1
  791.   RootDir$ = MID$(RootDir$, t%, 99)     'Save root dir name for later print
  792.   REDIM GTDir$(1000)                    'Number of sub-dir levels we can go
  793.  
  794.   c% = 0                                'Init temp counter
  795.   SC% = c%                               'Init sub-dir counter variable
  796.   GTDir$(c%) = Directory$               'First dir/level
  797.   DO
  798.     t$ = Dir$(GTDir$(c%))               'Get directory entry
  799.     IF t$ <> null$ THEN                 'Did we get one?
  800.       DO                                'Yep, let's get some more!
  801.         IF LEFT$(t$, 1) <> "." AND DirRecord.DirectoryFlag THEN 'Dir type?
  802.           SC% = SC% + 1                 'Yep, increment sub-dir count
  803.           GTDir$(SC%) = LEFT$(Directory$, INSTR(Directory$, all$)) + RTRIM$(DirRecord.EntryName) + all$
  804.         END IF
  805.         t$ = Dir$(null$)                'Get next entry
  806.       LOOP UNTIL t$ = null$             'Last one?
  807.     END IF                              'Yep...
  808.     IF c% <> SC% THEN                   'Got all our sub-dir names yet?
  809.       c% = c% + 1                       ' nope, try again
  810.       Directory$ = GTDir$(c%)           ' and reset dir variable
  811.     ELSE
  812.       EXIT DO
  813.     END IF
  814.   LOOP
  815.  
  816.   c% = 0                                'Init temp counter
  817.   FC = 0                                'Init file counter variable
  818.   TS# = 0                               'Init temp total variable
  819.   DO                                    'Start loop
  820.     t$ = Dir$(GTDir$(c%))               'Get directory entry
  821.     IF t$ <> null$ THEN                 'Did we get one?
  822.       DO                                'Yep, let's get some more!
  823.         TS# = TS# + DirRecord.EntrySize
  824.         IF LEFT$(t$, 1) <> "." AND DirRecord.DirectoryFlag <> 16 THEN 'Dir?
  825.           FC = FC + 1
  826.         END IF
  827.         t$ = Dir$(null$)                'Get next entry
  828.       LOOP UNTIL t$ = null$             'Last one?
  829.     END IF                              'Yep...
  830.     c% = c% + 1
  831.   LOOP UNTIL c% > SC%
  832.  
  833. PrintGrandTotals:
  834.  
  835.   ClearBox x1% - 1, y1%, x2%, y2%
  836.  
  837.   Center x1%, y1% + 1, y2%, "GrandTotals - " + RootDir$ + "..."
  838.   ReverseLine x1%, y1%, y2%
  839.   IF FC = 1 THEN t1$ = " total file" ELSE t1$ = " total files"
  840.   t$ = MaskIt$(LTRIM$(STR$(FC)), 15, ",") + t1$
  841.   Center x1% + 1, y1%, y2%, t$
  842.   IF SC = 1 THEN t1$ = " subdirectory" ELSE t1$ = " subdirectories"
  843.   t$ = MaskIt$(LTRIM$(STR$(SC%)), 15, ",") + t1$
  844.   Center x1% + 2, y1%, y2%, t$
  845.   IF TS# = 1 THEN t1$ = " Byte used" ELSE t1$ = " Bytes used"
  846.   t$ = MaskIt$(LTRIM$(STR$(TS#)), 15, ",") + t1$
  847.   Center x1% + 3, y1%, y2%, t$
  848.   ReverseLine x1% + 4, y1%, y2%
  849.   REDIM GTDir$(1)
  850.  
  851. ExitGrandTotals:
  852. END SUB
  853.  
  854. FUNCTION LastOccurrence% (text$, LookString$)
  855.  
  856.   ' This function will search through the string LookString$ for text$
  857.   ' and return the location of it's last occurence
  858.  
  859.   c% = False%                           'Init counter to 0
  860.   found% = True%                        'Init found flag
  861.   DO UNTIL found% = False%              'Keep looking for string until done
  862.     found% = INSTR(c% + 1, text$, LookString$) 'Found one!!
  863.     IF found% THEN c% = found%          'Save counter
  864.   LOOP
  865.  
  866.   LastOccurrence% = c%                  'Return count found
  867.  
  868. END FUNCTION
  869.  
  870. SUB ReverseLine (row%, lcol%, rcol%)
  871.  
  872.   ' This subroutine will reverse video the characters on row%, between
  873.   ' lcol% and rcol% (color only). It directly accesses the video memory
  874.   ' segment to do the color changes.
  875.  
  876.   PokeCount% = 0                        'Init character counter
  877.   length% = (rcol% - lcol% + 1) * 2     'Calculate ending offset
  878.   PosStart% = row% * 80 - 160 + lcol% * 2 + 1 'Video RAM addr begin POKEing
  879.   vidseg = VideoSegment                 'Get video memory segment address
  880.   DEF SEG = vidseg                      'Set memory seg address to our CRT
  881.   PokePos% = PosStart% + row% * 80      'Calc strt screen pos for POKE
  882.   PokeLength% = PokePos% + length%      'Calculate last POKEing address
  883.   DO                                    'Start column loop
  884.     d% = PEEK(PokePos%)                 'Do repeated calculation
  885.     POKE PokePos%, (d% AND 15) * 16 + d% / 16 'Reverse color
  886.     PokePos% = PokePos% + 2             'Increment POKE position counter
  887.   LOOP UNTIL PokePos% = PokeLength%     'Loop until end of line
  888.   DEF SEG                               'Return to BASIC segment
  889.  
  890. END SUB
  891.  
  892. SUB ScrollDown (text$)
  893.  
  894.   ' This subroutine will scroll the contents of a window down 1 line.
  895.   ' The text$ is what is to be inserted at the top of the window
  896.   ' after the scroll.
  897.  
  898.   InRegsX.AX = &H700 + 1                'function 7 + number of scroll lines
  899.   fg% = MainFg% * 256                   'Calc BH foreground
  900.   bg% = MainBg% * 4096                  'Calc BH background
  901.   InRegsX.BX = fg% + bg%                'Blanked line color
  902.   CH% = (FirstPrintRow% - 1) * 256      'CH=top row
  903.   InRegsX.CX = CH% + BoxCol%            'CL=left column
  904.   DH% = (LastPrintRow% - 1) * 256       'DH=bottom row
  905.   InRegsX.DX = DH% + BoxCol% + BoxLength%  'DL=right column
  906.   CALL INTERRUPTX(&H10, InRegsX, OutRegsX) 'Call interrupt 16
  907.   LOCATE FirstPrintRow%, BoxCol% + 1    'Locate cursor for top line print
  908.   PRINT text$;                          'Print the top line
  909.  
  910. END SUB
  911.  
  912. SUB ScrollUp (text$)
  913.  
  914.   ' This subroutine will scroll the contents of a window up one line.
  915.   ' The text$ is what is to be inserted at the bottom of the window
  916.   ' after the scroll.
  917.  
  918.   InRegsX.AX = &H600 + 1                'function 6 + number of scroll lines
  919.   fg% = MainFg% * 256                   'Calc BH foreground
  920.   bg% = MainBg% * 4096                  'Calc BH background
  921.   InRegsX.BX = fg% + bg%                'Blanked line color
  922.   CH% = (FirstPrintRow% - 1) * 256      'CH=top row
  923.   InRegsX.CX = CH% + BoxCol%            'CL=left column
  924.   DH% = (LastPrintRow% - 1) * 256       'DH=bottom row
  925.   InRegsX.DX = DH% + BoxCol% + BoxLength%  'DL=right column
  926.   CALL INTERRUPTX(&H10, InRegsX, OutRegsX) 'Call interrupt 16
  927.   LOCATE LastPrintRow%, BoxCol% + 1     'Locate cursor for bottom line print
  928.   PRINT text$;                          'Print the bottom line
  929.    
  930. END SUB
  931.  
  932. SUB SortDir (count%)
  933.  
  934.   Center FirstPrintRow%, BoxCol1%, BoxCol2%, "...One moment, I'm sorting 'em..."
  935.  
  936.   ' First, separate out dir entries
  937.   DIM temp(count%) AS DirType
  938.   MyDirCount% = 0
  939.   FOR c% = 1 TO count%
  940.     IF MyDir(c%).DirectoryFlag THEN
  941.       SWAP MyDir(c%), temp(c%)
  942.       MyDirCount% = MyDirCount% + 1
  943.     END IF
  944.   NEXT
  945.  
  946.   ' Sort everything BUT directory entries
  947.   DO
  948.     Swaps% = False%
  949.     FOR c% = 1 TO count% - 1
  950.       IF MyDir(c%).EntryName > MyDir(c% + 1).EntryName THEN
  951.         SWAP MyDir(c%), MyDir(c% + 1)
  952.         Swaps% = True%
  953.       END IF
  954.     NEXT c%
  955.   LOOP WHILE Swaps%
  956.  
  957.   ' Then, sort the dir entries
  958.   DO
  959.     Swaps% = False%
  960.     FOR c% = 1 TO count% - 1
  961.       IF temp(c%).EntryName > temp(c% + 1).EntryName THEN
  962.         SWAP temp(c%), temp(c% + 1)
  963.         Swaps% = True%
  964.       END IF
  965.     NEXT c%
  966.   LOOP WHILE Swaps%
  967.  
  968.   ' ... And insert em.
  969.   StartPoint% = count% - MyDirCount% + 1
  970.   d% = 1
  971.   FOR c% = StartPoint% TO count%
  972.     SWAP MyDir(d%), temp(c%)
  973.     d% = d% + 1
  974.   NEXT
  975.  
  976. END SUB
  977.  
  978. FUNCTION VideoSegment
  979.  
  980.   ' This is a handy function to return the memory address of the video
  981.   ' memory segment.
  982.  
  983.   VS = PEEK(&H63) + PEEK(&H64) * 256    'Get CRT controller port
  984.   IF VS = &H3B4 THEN
  985.     VS = &HB000                         'Video RAM segment address (mono)
  986.   ELSE
  987.     VS = &HB800                         'Video RAM segment address (color)
  988.   END IF
  989.  
  990.   VideoSegment = VS                     'Return variable value
  991.  
  992. END FUNCTION
  993.  
  994.